package org.jeecg.modules.message;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jettison.json.JSONTokener;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.modules.redis.client.JeecgRedisClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author jianxing
 * @Date 2022/03/10 00:15
 * @Description: 此注解相当于设置访问URL
 */
@Component
@Slf4j
@ServerEndpoint("/deviceListWebsocket/{requestId}") //此注解相当于设置访问URL
public class DeviceListWebSocket {

    private Session session;

    private String requestId;

    private static final String REDIS_TOPIC_NAME = "deviceListSocketHandler";

    @Resource
    private JeecgRedisClient jeecgRedisClient;

    /**
     * 缓存 webSocket连接到单机服务class中（整体方案支持集群）
     */
    private static CopyOnWriteArraySet<DeviceListWebSocket> webSockets = new CopyOnWriteArraySet<>();
    private static Map<String, Session> sessionPool = new HashMap<String, Session>();
    private static Map<String, String> deviceListener = new HashMap<String, String>();


    @OnOpen
    public void onOpen(Session session, @PathParam(value = "requestId") String requestId) {
        try {
            if(this.session != null)
                log.info("Cuurent session Id is :" + session.getId());
            else
                log.info("Cuurent session Id is :" + null);
            this.session = session;
            this.requestId = requestId;
            webSockets.add(this);
            sessionPool.put(this.requestId, session);
            log.info("【websocket消息】有新的List连接，总数为:" + webSockets.size());
        } catch (Exception e) {
        }
    }

    @OnClose
    public void onClose() {
        try {
            webSockets.remove(this);
            deviceListener.remove(this.requestId);
            sessionPool.remove(this.requestId);
            log.info("【websocket消息】List连接断开，总数为:" + webSockets.size());
        } catch (Exception e) {
        }
    }


    /**
     * 服务端推送消息
     *
     * @param
     * @param message
     */
    public void pushMessage(String deviceId, String message) {
        try {
            sessionPool.forEach((key,val)->{
                if(deviceListener.containsKey(key)){
                    if(deviceListener.get(key).indexOf(deviceId) > -1){
                        val.getAsyncRemote().sendText(message);
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 服务器端推送消息
     */
    public void pushMessage(String message) {
        try {
            webSockets.forEach(ws -> ws.session.getAsyncRemote().sendText(message));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @OnMessage
    public void onMessage(String message) {
        log.debug("【websocket消息】收到客户端消息:" + message);
        JSONObject obj = JSON.parseObject(message);
        if(obj.containsKey("cmd")){
            if(obj.getString("cmd").equals("resetDevices")){
                String deviceList = obj.getString("devices");
                String id = obj.getString("id");
                deviceListener.put(id, deviceList);
            }
        }
    }

//    /**
//     * 后台发送消息到redis
//     *
//     * @param message
//     */
//    public void sendMessage(String message) {
//        log.info("【websocket消息】广播消息:" + message);
//        BaseMap baseMap = new BaseMap();
//        baseMap.put("deviceId", "");
//        baseMap.put("message", message);
//        jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap);
//    }

//    /**
//     * 此为单点消息
//     *
//     * @param userId
//     * @param message
//     */
//    public void sendMessage(String deviceId, String message) {
//        BaseMap baseMap = new BaseMap();
//        baseMap.put("deviceId", deviceId);
//        baseMap.put("message", message);
//        jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap);
//    }

//    /**
//     * 此为单点消息(多人)
//     *
//     * @param userIds
//     * @param message
//     */
//    public void sendMessage(String[] deviceIds, String message) {
//        for (String deviceId : deviceIds) {
//            sendMessage(deviceId, message);
//        }
//    }
}
